package com.mark.web.data.service.impl;

import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.mark.common.ServerResponse;
import com.mark.common.exception.Campuso2oException;
import com.mark.web.data.entity.po.Category;
import com.mark.web.data.entity.vo.CategoryVo;
import com.mark.web.data.exception.CategoryException;
import com.mark.web.data.mapper.CategoryMapper;
import com.mark.web.data.service.ICategoryService;
import com.mark.web.data.util.JsonUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @Description: 商品种类业务逻辑实现
 * @Author: Mark
 * @CreateDate: 2018/8/14.
 * @Version: 2.0
 * @Copyright : 豆浆油条个人非正式工作室
 */
@Service("iCategoryService")
@Slf4j
public class CategoryServiceImpl implements ICategoryService {

    private final CategoryMapper categoryMapper;
    private final StringRedisTemplate redisTemplate;

    public CategoryServiceImpl(CategoryMapper categoryMapper, StringRedisTemplate redisTemplate) {
        this.categoryMapper = categoryMapper;
        this.redisTemplate = redisTemplate;
    }

    @Override
    public void addCategory(String categoryName, Integer parentId, String imageAddress) {
        Category category = new Category();
        category.setProductCategoryName(categoryName);
        category.setParentId(parentId);
        category.setEnableStatus(true);
        category.setImageAddress(imageAddress);
        category.setPriority(1);
        int rowCount = categoryMapper.insert(category);
        if (rowCount > 0) {
            String redisToken = "categoryList" + parentId;
            redisTemplate.delete(redisToken);
        }
        throw new Campuso2oException("添加商品种类失败!");
    }

    @Override
    public void updateCategoryName(Integer categoryId, String categoryNewName) {
        Category categoryNew = new Category();
        categoryNew.setId(categoryId);
        categoryNew.setProductCategoryName(categoryNewName);
        int rowCount = categoryMapper.updateByPrimaryKeySelective(categoryNew);
        if (rowCount > 0) {
            String redisToken = "category" + categoryId;
            //如果是更新操作从redis中删除，保证Redis缓存中存放的是最新的数据
            redisTemplate.delete(redisToken);
            Category category = categoryMapper.selectByPrimaryKey(categoryId);
            redisTemplate.delete("categoryList" + category.getParentId());
        }
        throw new Campuso2oException("更新品类名字失败!");
    }

    @Override
    public List<CategoryVo> getChildrenParallelCategory(Integer categoryId) {
        //种类信息放入redis
        List<Category> categoryList;
        categoryList = categoryMapper.selectCategoryChildrenByParentId(categoryId);

        List<CategoryVo> categoryVoList = Lists.newArrayList();
        if (CollectionUtils.isNotEmpty(categoryList)) {
            categoryVoList = categoryList.stream().map(CategoryVo::new).collect(Collectors.toList());
        }
        return categoryVoList;
    }

    @Override
    public List<Integer> selectCategoryAndChildrenById(Integer categoryId) {
        Set<Category> categorySet = Sets.newHashSet();
        this.findChildCategory(categorySet, categoryId);
        List<Integer> categoryIdList = Lists.newArrayList();
        for (Category category : categorySet) {
            categoryIdList.add(category.getId());
        }
        return categoryIdList;
    }

    //递归函数,算出子节点
    private Set<Category> findChildCategory(Set<Category> categorySet, Integer categoryId) {
        try {
            String redisToken = "category" + categoryId;
            //String categoryJsonStr = RedisShardedPoolUtil.get(redisToken);
            String categoryJsonStr = redisTemplate.opsForValue().get(redisToken);
            Category category = JsonUtil.string2Obj(categoryJsonStr, Category.class);//如果redis中存在就取redis中的值
            if (category != null) {
                log.info("正在从Redis缓存中取【category" + categoryId + "】数据");
            } else {
                category = categoryMapper.selectByPrimaryKey(categoryId);
                //RedisShardedPoolUtil.set(redisToken, JsonUtil.obj2String(category));
                redisTemplate.opsForValue().set(redisToken, JsonUtil.obj2String(category));
            }
            if (category != null) {
                categorySet.add(category);
            }
            //查找子节点,递归算法一定要有一个退出的条件
            Integer parentId = categoryId;
            List<Category> categoryList = categoryMapper.selectCategoryChildrenByParentId(parentId);
            for (Category categoryItem : categoryList) {
                this.findChildCategory(categorySet, categoryItem.getId());
            }
            return categorySet;
        } catch (Exception e) {
            throw new CategoryException("findChildCategory", e.getClass() + e.getMessage());
        }
    }
}
